package com.cencat.route.controller;

import com.cencat.common.result.Result;
import com.cencat.route.dto.RoutePlanningRequestDTO;
import com.cencat.route.dto.RouteOptimizationDTO;
import com.cencat.route.dto.DeliveryPlanDTO;
import com.cencat.route.vo.RoutePlanVO;
import com.cencat.route.vo.OptimizationResultVO;
import com.cencat.route.vo.DeliveryPlanVO;
import com.cencat.route.service.RoutePlanningService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;

/**
 * 路线规划控制器
 * 
 * @author cencat
 * @since 2024-01-01
 */
@Slf4j
@RestController
@RequestMapping("/api/route-planning")
@RequiredArgsConstructor
@Validated
@Tag(name = "路线规划", description = "智能路线规划与优化相关接口")
public class RoutePlanningController {

    private final RoutePlanningService routePlanningService;

    /**
     * 智能路线规划
     */
    @PostMapping("/plan")
    @Operation(summary = "智能路线规划", description = "基于多目标优化算法进行智能路线规划")
    @PreAuthorize("hasAuthority('route:plan')")
    public Result<RoutePlanVO> planRoute(
            @Parameter(description = "路线规划请求参数", required = true)
            @RequestBody @Valid RoutePlanningRequestDTO requestDTO) {
        try {
            RoutePlanVO planResult = routePlanningService.planRoute(requestDTO);
            return Result.success(planResult);
        } catch (Exception e) {
            log.error("智能路线规划失败", e);
            return Result.error("智能路线规划失败: " + e.getMessage());
        }
    }

    /**
     * 批量路线规划
     */
    @PostMapping("/batch-plan")
    @Operation(summary = "批量路线规划", description = "批量进行多条路线的智能规划")
    @PreAuthorize("hasAuthority('route:plan')")
    public Result<List<RoutePlanVO>> batchPlanRoutes(
            @Parameter(description = "批量规划请求参数", required = true)
            @RequestBody @Valid List<RoutePlanningRequestDTO> requestList) {
        try {
            List<RoutePlanVO> planResults = routePlanningService.batchPlanRoutes(requestList);
            return Result.success(planResults);
        } catch (Exception e) {
            log.error("批量路线规划失败", e);
            return Result.error("批量路线规划失败: " + e.getMessage());
        }
    }

    /**
     * 路线优化
     */
    @PostMapping("/optimize")
    @Operation(summary = "路线优化", description = "对现有路线进行多目标优化")
    @PreAuthorize("hasAuthority('route:optimize')")
    public Result<OptimizationResultVO> optimizeRoute(
            @Parameter(description = "路线优化参数", required = true)
            @RequestBody @Valid RouteOptimizationDTO optimizationDTO) {
        try {
            OptimizationResultVO result = routePlanningService.optimizeRoute(optimizationDTO);
            return Result.success(result);
        } catch (Exception e) {
            log.error("路线优化失败", e);
            return Result.error("路线优化失败: " + e.getMessage());
        }
    }

    /**
     * 实时路线调整
     */
    @PostMapping("/adjust")
    @Operation(summary = "实时路线调整", description = "基于实时交通和订单情况调整路线")
    @PreAuthorize("hasAuthority('route:adjust')")
    public Result<RoutePlanVO> adjustRoute(
            @Parameter(description = "路线ID", required = true)
            @RequestParam @NotNull Long routeId,
            @Parameter(description = "调整参数", required = true)
            @RequestBody @NotNull Map<String, Object> adjustParams) {
        try {
            RoutePlanVO adjustedRoute = routePlanningService.adjustRoute(routeId, adjustParams);
            return Result.success(adjustedRoute);
        } catch (Exception e) {
            log.error("实时路线调整失败, routeId: {}", routeId, e);
            return Result.error("实时路线调整失败: " + e.getMessage());
        }
    }

    /**
     * 配送计划生成
     */
    @PostMapping("/delivery-plan")
    @Operation(summary = "配送计划生成", description = "基于路线规划生成详细的配送计划")
    @PreAuthorize("hasAuthority('route:plan')")
    public Result<DeliveryPlanVO> generateDeliveryPlan(
            @Parameter(description = "配送计划参数", required = true)
            @RequestBody @Valid DeliveryPlanDTO planDTO) {
        try {
            DeliveryPlanVO deliveryPlan = routePlanningService.generateDeliveryPlan(planDTO);
            return Result.success(deliveryPlan);
        } catch (Exception e) {
            log.error("配送计划生成失败", e);
            return Result.error("配送计划生成失败: " + e.getMessage());
        }
    }

    /**
     * 时间窗优化
     */
    @PostMapping("/time-window-optimize")
    @Operation(summary = "时间窗优化", description = "优化配送时间窗以提高效率")
    @PreAuthorize("hasAuthority('route:optimize')")
    public Result<Map<String, Object>> optimizeTimeWindow(
            @Parameter(description = "路线ID", required = true)
            @RequestParam @NotNull Long routeId,
            @Parameter(description = "优化参数", required = true)
            @RequestBody @NotNull Map<String, Object> params) {
        try {
            Map<String, Object> result = routePlanningService.optimizeTimeWindow(routeId, params);
            return Result.success(result);
        } catch (Exception e) {
            log.error("时间窗优化失败, routeId: {}", routeId, e);
            return Result.error("时间窗优化失败: " + e.getMessage());
        }
    }

    /**
     * 路线可行性分析
     */
    @PostMapping("/feasibility-analysis")
    @Operation(summary = "路线可行性分析", description = "分析路线规划的可行性和风险")
    @PreAuthorize("hasAuthority('route:analyze')")
    public Result<Map<String, Object>> analyzeFeasibility(
            @Parameter(description = "路线规划参数", required = true)
            @RequestBody @Valid RoutePlanningRequestDTO requestDTO) {
        try {
            Map<String, Object> analysis = routePlanningService.analyzeFeasibility(requestDTO);
            return Result.success(analysis);
        } catch (Exception e) {
            log.error("路线可行性分析失败", e);
            return Result.error("路线可行性分析失败: " + e.getMessage());
        }
    }

    /**
     * 获取优化建议
     */
    @GetMapping("/suggestions/{routeId}")
    @Operation(summary = "获取优化建议", description = "基于历史数据和AI分析提供路线优化建议")
    @PreAuthorize("hasAuthority('route:analyze')")
    public Result<List<Map<String, Object>>> getOptimizationSuggestions(
            @Parameter(description = "路线ID", required = true)
            @PathVariable @NotNull Long routeId) {
        try {
            List<Map<String, Object>> suggestions = routePlanningService.getOptimizationSuggestions(routeId);
            return Result.success(suggestions);
        } catch (Exception e) {
            log.error("获取优化建议失败, routeId: {}", routeId, e);
            return Result.error("获取优化建议失败: " + e.getMessage());
        }
    }

    /**
     * 路线模拟
     */
    @PostMapping("/simulate")
    @Operation(summary = "路线模拟", description = "模拟路线执行过程，预测配送效果")
    @PreAuthorize("hasAuthority('route:simulate')")
    public Result<Map<String, Object>> simulateRoute(
            @Parameter(description = "路线规划参数", required = true)
            @RequestBody @Valid RoutePlanningRequestDTO requestDTO,
            @Parameter(description = "模拟参数")
            @RequestParam(required = false) Map<String, Object> simulationParams) {
        try {
            Map<String, Object> simulationResult = routePlanningService.simulateRoute(requestDTO, simulationParams);
            return Result.success(simulationResult);
        } catch (Exception e) {
            log.error("路线模拟失败", e);
            return Result.error("路线模拟失败: " + e.getMessage());
        }
    }

    /**
     * 多目标优化
     */
    @PostMapping("/multi-objective-optimize")
    @Operation(summary = "多目标优化", description = "基于多个优化目标进行路线规划")
    @PreAuthorize("hasAuthority('route:optimize')")
    public Result<OptimizationResultVO> multiObjectiveOptimize(
            @Parameter(description = "优化参数", required = true)
            @RequestBody @NotNull Map<String, Object> objectives) {
        try {
            OptimizationResultVO result = routePlanningService.multiObjectiveOptimize(objectives);
            return Result.success(result);
        } catch (Exception e) {
            log.error("多目标优化失败", e);
            return Result.error("多目标优化失败: " + e.getMessage());
        }
    }

    /**
     * 动态路线调度
     */
    @PostMapping("/dynamic-dispatch")
    @Operation(summary = "动态路线调度", description = "基于实时情况进行动态路线调度")
    @PreAuthorize("hasAuthority('route:dispatch')")
    public Result<List<RoutePlanVO>> dynamicDispatch(
            @Parameter(description = "调度参数", required = true)
            @RequestBody @NotNull Map<String, Object> dispatchParams) {
        try {
            List<RoutePlanVO> dispatchResult = routePlanningService.dynamicDispatch(dispatchParams);
            return Result.success(dispatchResult);
        } catch (Exception e) {
            log.error("动态路线调度失败", e);
            return Result.error("动态路线调度失败: " + e.getMessage());
        }
    }

    /**
     * 路线效果评估
     */
    @PostMapping("/evaluate")
    @Operation(summary = "路线效果评估", description = "评估路线规划的执行效果")
    @PreAuthorize("hasAuthority('route:evaluate')")
    public Result<Map<String, Object>> evaluateRoute(
            @Parameter(description = "路线ID", required = true)
            @RequestParam @NotNull Long routeId,
            @Parameter(description = "评估参数")
            @RequestBody Map<String, Object> evaluationParams) {
        try {
            Map<String, Object> evaluation = routePlanningService.evaluateRoute(routeId, evaluationParams);
            return Result.success(evaluation);
        } catch (Exception e) {
            log.error("路线效果评估失败, routeId: {}", routeId, e);
            return Result.error("路线效果评估失败: " + e.getMessage());
        }
    }

    /**
     * 获取规划历史
     */
    @GetMapping("/history")
    @Operation(summary = "获取规划历史", description = "获取路线规划的历史记录")
    @PreAuthorize("hasAuthority('route:view')")
    public Result<List<Map<String, Object>>> getPlanningHistory(
            @Parameter(description = "路线ID")
            @RequestParam(required = false) Long routeId,
            @Parameter(description = "开始时间")
            @RequestParam(required = false) String startTime,
            @Parameter(description = "结束时间")
            @RequestParam(required = false) String endTime,
            @Parameter(description = "页码")
            @RequestParam(defaultValue = "1") Integer page,
            @Parameter(description = "页大小")
            @RequestParam(defaultValue = "20") Integer size) {
        try {
            List<Map<String, Object>> history = routePlanningService.getPlanningHistory(
                    routeId, startTime, endTime, page, size);
            return Result.success(history);
        } catch (Exception e) {
            log.error("获取规划历史失败", e);
            return Result.error("获取规划历史失败: " + e.getMessage());
        }
    }

    /**
     * 路线对比分析
     */
    @PostMapping("/compare")
    @Operation(summary = "路线对比分析", description = "对比分析多个路线方案的优劣")
    @PreAuthorize("hasAuthority('route:analyze')")
    public Result<Map<String, Object>> compareRoutes(
            @Parameter(description = "路线ID列表", required = true)
            @RequestBody @NotNull List<Long> routeIds,
            @Parameter(description = "对比维度")
            @RequestParam(required = false) List<String> dimensions) {
        try {
            Map<String, Object> comparison = routePlanningService.compareRoutes(routeIds, dimensions);
            return Result.success(comparison);
        } catch (Exception e) {
            log.error("路线对比分析失败, routeIds: {}", routeIds, e);
            return Result.error("路线对比分析失败: " + e.getMessage());
        }
    }

    /**
     * 智能推荐路线
     */
    @PostMapping("/recommend")
    @Operation(summary = "智能推荐路线", description = "基于机器学习算法推荐最优路线方案")
    @PreAuthorize("hasAuthority('route:recommend')")
    public Result<List<RoutePlanVO>> recommendRoutes(
            @Parameter(description = "推荐参数", required = true)
            @RequestBody @NotNull Map<String, Object> recommendParams) {
        try {
            List<RoutePlanVO> recommendations = routePlanningService.recommendRoutes(recommendParams);
            return Result.success(recommendations);
        } catch (Exception e) {
            log.error("智能推荐路线失败", e);
            return Result.error("智能推荐路线失败: " + e.getMessage());
        }
    }

    /**
     * 获取算法配置
     */
    @GetMapping("/algorithm-config")
    @Operation(summary = "获取算法配置", description = "获取路线规划算法的配置参数")
    @PreAuthorize("hasAuthority('route:config')")
    public Result<Map<String, Object>> getAlgorithmConfig() {
        try {
            Map<String, Object> config = routePlanningService.getAlgorithmConfig();
            return Result.success(config);
        } catch (Exception e) {
            log.error("获取算法配置失败", e);
            return Result.error("获取算法配置失败: " + e.getMessage());
        }
    }

    /**
     * 更新算法配置
     */
    @PutMapping("/algorithm-config")
    @Operation(summary = "更新算法配置", description = "更新路线规划算法的配置参数")
    @PreAuthorize("hasAuthority('route:config')")
    public Result<Void> updateAlgorithmConfig(
            @Parameter(description = "算法配置", required = true)
            @RequestBody @NotNull Map<String, Object> config) {
        try {
            routePlanningService.updateAlgorithmConfig(config);
            return Result.success();
        } catch (Exception e) {
            log.error("更新算法配置失败", e);
            return Result.error("更新算法配置失败: " + e.getMessage());
        }
    }
}